package com.atguigu.tingshu.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.model.payment.PaymentInfo;
import com.atguigu.tingshu.model.user.VipServiceConfig;
import com.atguigu.tingshu.order.helper.SignHelper;
import com.atguigu.tingshu.order.mapper.OrderDetailMapper;
import com.atguigu.tingshu.order.mapper.OrderInfoMapper;
import com.atguigu.tingshu.order.service.OrderInfoService;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.user.client.VipServiceConfigFeignClient;
import com.atguigu.tingshu.vo.order.OrderDerateVo;
import com.atguigu.tingshu.vo.order.OrderDetailVo;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import com.atguigu.tingshu.vo.order.TradeVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private AlbumInfoFeignClient albumInfoFeignClient;

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    @Autowired
    private VipServiceConfigFeignClient vipServiceConfigFeignClient;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 订单结算页
     *
     * @param userId
     * @return
     */
    @Override
    public OrderInfoVo trade(TradeVo tradeVo, Long userId) {
        // 创建返回对象
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        // 原始金额
        BigDecimal originalAmount = new BigDecimal("0.00");//原始金额
        BigDecimal derateAmount = new BigDecimal("0.00");//减免金额
        BigDecimal orderAmount = new BigDecimal("0.00");//订单金额
        // 订单明细列表
        List<OrderDetailVo> orderDetailVoList = new ArrayList<>();
        // 订单减免明细列表
        List<OrderDerateVo> orderDerateVoList = new ArrayList<>();

        // 获取用户信息
        Result<UserInfoVo> userInfoVoResult = userInfoFeignClient.getUserInfoVo(userId);
        Assert.notNull(userInfoVoResult, "查询用户信息失败");
        UserInfoVo userInfoVo = userInfoVoResult.getData();
        Assert.notNull(userInfoVo, "查询用户信息失败");
        // 根据购买类型判断
        if (tradeVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_ALBUM)) {//专辑
            // 判断这个用户是否购买过专辑;
            Result<Boolean> isPaidAlbumResult = this.userInfoFeignClient.isPaidAlbum(tradeVo.getItemId());
            Assert.notNull(isPaidAlbumResult, "查询用户是否购买专辑失败");
            Boolean result = isPaidAlbumResult.getData();
            if (result) {
                //  用户购买过专辑
                throw new GuiguException(ResultCodeEnum.REPEAT_BUY_ERROR);
            }
            //  购买专辑；
            Result<AlbumInfo> albumInfoResult = albumInfoFeignClient.getAlbumInfo(tradeVo.getItemId());
            Assert.notNull(albumInfoResult, "查询专辑信息失败");
            AlbumInfo albumInfo = albumInfoResult.getData();
            Assert.notNull(albumInfo, "查询专辑信息失败");
            // 获取到原价
            originalAmount = albumInfo.getPrice();
            // 判断用户的身份
            if (userInfoVo.getIsVip().intValue() == 1 && userInfoVo.getVipExpireTime().after(new Date())) {// 用户是否是vip且vip没有过期
                // 是vip，判断是否有折扣
                if (albumInfo.getVipDiscount().compareTo(new BigDecimal("-1")) > 0) {
                    // > 0有折扣，   计算减免后的金额：100, 打8折 等价于 20%折扣;  100*(10-8)/10;
                    /*
                    打8折 = 原价 × 0.8 = 支付80%的金额
                    折扣率 = 100% - 80% = 20%
                    折扣金额 = 原价 × 20%
                     */
                    derateAmount = albumInfo.getPrice().multiply(new BigDecimal("10").subtract(albumInfo.getVipDiscount())).divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP);
                }
            } else {
                if (albumInfo.getDiscount().compareTo(new BigDecimal("-1")) > 0) {
                    // 普通折扣
                    derateAmount = albumInfo.getPrice().multiply(new BigDecimal("10").subtract(albumInfo.getDiscount())).divide(new BigDecimal("10"));
                }
            }
            // 实际金额     原始总金额 - 折扣金额
            orderAmount = originalAmount.subtract(derateAmount);
            // 订单明细
            // 创建订单明细对象
            OrderDetailVo orderDetailVo = new OrderDetailVo();
            orderDetailVo.setItemName(albumInfo.getAlbumTitle());
            orderDetailVo.setItemUrl(albumInfo.getCoverUrl());
            orderDetailVo.setItemId(tradeVo.getItemId());
            orderDetailVo.setItemPrice(orderAmount);
            orderDetailVoList.add(orderDetailVo);
            // 订单减免明细列表
            if (derateAmount.compareTo(new BigDecimal("0.00")) > 0) {
                OrderDerateVo orderDerateVo = new OrderDerateVo();
                // 赋值
                orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_ALBUM_DISCOUNT);
                orderDerateVo.setDerateAmount(derateAmount);
                orderDerateVo.setRemarks("专辑折扣");
                orderDerateVoList.add(orderDerateVo);
            }
        } else if (tradeVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_TRACK)) {
            // 购买声音

        } else {
            // 购买vip    vip_service_config.id;
            Long itemId = tradeVo.getItemId();
            Result<VipServiceConfig> vipServiceConfigResult = vipServiceConfigFeignClient.getVipServiceConfig(itemId);
            Assert.notNull(vipServiceConfigResult, "查询vip服务配置失败");
            VipServiceConfig vipServiceConfig = vipServiceConfigResult.getData();
            Assert.notNull(vipServiceConfig, "查询vip服务配置失败");
            // 设置原始价格
            originalAmount = vipServiceConfig.getPrice();
            // 减免金额
            derateAmount = originalAmount.subtract(vipServiceConfig.getDiscountPrice());
            // 实际金额
            orderAmount = vipServiceConfig.getDiscountPrice();
            // 订单明细
            OrderDetailVo orderDetailVo = new OrderDetailVo();
            orderDetailVo.setItemName(vipServiceConfig.getName());
            orderDetailVo.setItemUrl(vipServiceConfig.getImageUrl());
            orderDetailVo.setItemId(itemId);
            orderDetailVo.setItemPrice(orderAmount);
            orderDetailVoList.add(orderDetailVo);
            // 减免明细
            if (derateAmount.compareTo(new BigDecimal("0.00")) > 0) {
                //  创建对象并赋值;
                OrderDerateVo orderDerateVo = new OrderDerateVo();
                orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_VIP_SERVICE_DISCOUNT);
                orderDerateVo.setDerateAmount(derateAmount);
                orderDerateVo.setRemarks("vip服务折扣");
                orderDerateVoList.add(orderDerateVo);
            }
        }
        // 声明一个订单交易号
        String tradeNo = UUID.randomUUID().toString().replaceAll("-", "");
        // 存储到缓存中，订单过期时间,判断key可以使用setnx+setex；利用锁的思想
        String tradeNoKey = userId + ":" + tradeNo;
        redisTemplate.opsForValue().set(tradeNoKey, tradeNo,3, TimeUnit.MINUTES);
        orderInfoVo.setTradeNo(tradeNo);
        orderInfoVo.setPayWay("");
        orderInfoVo.setItemType(tradeVo.getItemType());
        orderInfoVo.setOriginalAmount(originalAmount);
        orderInfoVo.setDerateAmount(derateAmount);
        orderInfoVo.setOrderAmount(orderAmount);
        orderInfoVo.setOrderDetailVoList(orderDetailVoList);
        orderInfoVo.setOrderDerateVoList(orderDerateVoList);
        orderInfoVo.setTimestamp(SignHelper.getTimestamp());
        //  签名；防止用户非法篡改数据保证接口的安全性!
        String orderJson = JSONObject.toJSONString(orderInfoVo);
        String sign = SignHelper.getSign(JSONObject.parseObject(orderJson, Map.class));
        orderInfoVo.setSign(sign);
        //  返回数据
        return orderInfoVo;
    }

}
